\section{Profiling com gprof}
\subsection{Introdução}
	\tab É comum uma pequena parte de um código ocupar uma grande parte do tempo de execução de um programa. Profiling é uma análise de comportamento de um programa com base nas informações colhidas durante a execução do mesmo, com o objetivo de determinar quais partes do programa se pode otimizar para ganhos de velocidade e redução no uso de memória.

	Um \textit{Profiler} coleta dados como tempo, frequência e duração das chamadas das funções, interrupções de hardware, erros do sistema operacional entre outros e mostra resumo dos eventos observados (um \textit{profile}). Em programas seqüenciais, um profile é suficiente para ver as partes do código que precisam de atenção.

	O \textbf{gprof} é um profiler GNU para C, C++, Pascal e Fortran que funciona atravéz de interrupções no sistema operacional em intervalos específicos para colher amostras dos dados. Profilers que operam assim são menos exatos e específicos, mas permitem o programa rodar na velocidade quase máxima.

\section{Preparando o código - Compilando}

	\tab Este programa em 'C' será usado como exemplo para compilação com \textit{gcc} e profiling com \textit{gprof} (seção \ref{exemplo}) :\\
\sffamily
\label{teste}
	\verb+## Exemplo.c ##+\\
	\verb+#include <stdio.h>+\\
	\\
	void a() $\lbrace\ $\\
  	\tab	int x, y;\\
  	\tab	for (x=0; x \verb+<+ 10000; x++)\\
    	\tab	\tab	y = x;\\
	$\rbrace $\\
	\\
	void b() $\lbrace $\\
  	\tab	int h, k;\\
	\tab	for (h=0; h \verb+<+ 20000; h++)\\
  	\tab	\tab	k = h;\\
	\tab	a();\\
	$\rbrace $\\
	\\
	int main() $\lbrace $\\
	\tab	int i;\\
  	\tab	for (i=0; i \verb+<+ 30000; i++) $\lbrace $\\
    	\tab	\tab	a();\\
    	\tab	\tab	b();\\
  	\tab	$\rbrace $ \\
  	return 0;\\
	$\rbrace $\\
\rmfamily
	\tab Este programa cria \textit{loops} de chamadas de funções que fazem laços de atribuições e outras chamadas.\\

	\tab Antes de fazer o profile do código, é preciso compilá-lo e executá-lo:\\
\sffamily
	\tab \tab \$ gcc -pg teste.c -o teste		(compilação com gcc criando o executável 'teste' )\\
	\tab \tab \$ ./teste				(execução do executável criado acima)\\
\rmfamily
	\tab O parâmetro \textit{-pg} diz ao compilador para criar um arquivo durante a execução do programa chamado \textit{gmon.out} com informações sobre a execução que serão interpretadas pelo gprof.

	\tab O comando para utilizar o gprof é:\\
\sffamily
	\tab \tab \$ gprof teste \verb+<parâmetro>+\\
\rmfamily
	\tab O parâmetro pode ser:
	\begin{itemize}
		\item -P	(Flat)
		\item -Q	(Call Graph)
		\item -A	(Annotated Source)
	\end{itemize}

\section{Tipos de Profile/Perfil}
\subsection{Flat (-P)}
	\tab O perfil 'flat' (\textit{plano}) mostra o tempo total que o programa executa cada função. A tabela com as informações está dividida em:
	\begin{itemize}
	\item \verb+%+ \textbf{time}: Percentagem de tempo que a função ocupa do tempo total.
	\item \textbf{cumulative seconds}: Tempo total em segundos que o computador gastou executando esta função e todas acima desta.
	\item \textbf{self seconds}: Tempo total em segundos de execução apenas desta função.
	\item \textbf{calls}: Número de vezes que a função foi chamada.
	\item \textbf{self ms/call}: Tempo médio em milisegundos gasto em cada chamada desta função.
	\item \textbf{total ms/call}: Tempo médio em milisegundos gasto na chamada desta função e suas chamadas anteriores.
	\item \textbf{name}: Nome da função. Este perfil lista por ordem alfabética as funções.
	\end{itemize}

	Funções que não foram chamadas durante a compilação para o profiling não são citadas caso o comando '-Z' não seja dado.\\
\subsection{Call Graph (-Q)}
	\tab  O perfil 'call graph' mostra a quantidade de tempo gasta em cada função e suas chamadas internas (\textit{children}) para outras funções. É possível identificar funções que, apesar de não terem gasto muito tempo para serem executadas, chamam outras funções que gastam muito tempo para serem executadas.

	É feita uma divisão por entradas (\textit{entries}). Em cada entrada, a primeira linha começa com uma designação numérica (como \textbf{[1]}) e termina com o nome da função que representa. A próxima linha identifica qual função chamou esta, e em seguida as funções que esta chama.
	
	A linha primária se divide em:\\
	\begin{itemize}
	\item \textbf{index} - Entradas são numeradas com inteiros consecutivos.
	\item \verb+%+ \textbf{time} - Tempo total gasto nesta função incluindo chamadas internas e chamadas de outras funções para esta.
	\item \textbf{self} - Tempo gasto apenas nesta função.
	\item \textbf{children} - Tempo gasto nas chamadas internas desta função.
	\item \textbf{called} - Número de chamadas desta função.
	\item \textbf{name} - Nome da função seguido do numero de \textit{index} da mesma.
	\end{itemize}

	As linhas seguintes se dividem em:
	\begin{itemize}
	\item \textbf{self} - Tempo estimado de execução sem chamadas internas.
	\item \textbf{children} - Tempo de execução das chamatas internas.
	\item \textbf{called} - Número de vezes que foi chamada seguida do número total de chamadas não-recursivas das funções que o chamaram.
	\item \textbf{name/index} - Nome e numero 'index' da função que chamou esta. Se a função que chamou for recursiva, mostra o número de chamadas recursivas.
	\end{itemize}
\subsection{Annotated Source (-A)}
	\tab O perfil 'Annotated Source' mostra o código fonte do programa com o número de vezes que cada função foi chamada.\\

	Para uma análise mais detalhada, linha-por-linha, deve-se colocar o comando '-g' durante a compilação com o gcc. Durante a chamada do gprof, os comandos: '-l', '-x' e '-i' podem ser especificados:

\begin{itemize}
\item \textbf{-l} : Faz um profiling linha por linha.
\item \textbf{-x} : Garante que cada linha seja marcada pelo menos uma vez.
\item \textbf{-i} : Caso o gprof não localize o código fonte, este comando deve ser especificado.
\end{itemize}
\section{Exemplo interpretado}
\label{exemplo}
	\tab Depois de compilar o 'teste.c' (seção \ref{teste}), passaremos pelos 3 perfis do GPROF.
\subsection{Exemplo Flat}
	\sffamily
	\tab \tab \$ gprof teste -p\\
	\rmfamily
\begin{center}
 \includegraphics[bb=0 0 422 87]{flat.png}
 % flat.png: 422x87 pixel, 72dpi, 14.89x3.07 cm, bb=0 0 422 87
\end{center}

	Este perfil mostra que o programa demorou 3.68 segundos para ser executado, sendo a função \textbf{b()} responsável por 2.01 segundos , 30000 chamadas (que duraram 67ms cada) enquanto \textbf{a()} demorou 1.68 segundos, 60000 chamadas (que duraram 27ms) cada.

\subsection{Exemplo Call Graph}
	\sffamily
	\tab \tab \$ gprof teste -q\\
	\rmfamily
\begin{center}
\hspace*{-1cm}\includegraphics[bb=0 0 514 300]{graph.png}
 % graph.png: 514x300 pixel, 72dpi, 18.13x10.58 cm, bb=0 0 514 300
\end{center}
	Este perfil mostra que a função \textbf{b()} demorou 2.01 segundos sendo que, desde, 0.83 foram gastos chamando \textbf{a()}.

\subsection{Exemplo Annotated Source line-by-line}
	\sffamily
	\tab \tab \$ gcc -pg -g teste -o teste \\
	\tab \tab \$ gprof teste -a -l -x\\
	\rmfamily
\begin{center}
 \includegraphics[bb=0 0 356 618]{source.png}
 % source.png: 356x618 pixel, 72dpi, 12.56x21.80 cm, bb=0 0 356 618
\end{center}
	Este perfil mostra que a linha 3 foi chamada 60000 vezes e a linha 9, 30000 vezes, em um total de 90000 linhas executadas.
%\end{document}

\bibliography{otimizacaobib}
